const db2 = require('./db/db2');
const { Server } = require("socket.io");

module.exports = function (server) {
  const io = new Server(server, {
    cors: {
      origin: ['http://localhost:3000', 'http://81.68.151.74']
    }
  })

  // ws成功连接时触发
  io.on('connection', function (socket) {
    console.log('后端socket已连接...: ', socket.handshake.query.user)

    socket.on('apply add friend', async (msg) => {
      const { from, to } = msg;
      const r = await db2.find('chat', { $or: [{ userName: to }, { uid: parseInt(to) }] });
      if (r && r.length > 0) {
        const addMeData = r[0].applyMeFriends.find(item => item.userName === from);
        const sockets = await io.fetchSockets();
        sockets.forEach((item) => {
          if (item.handshake.query.user === r[0].userName) {
            item.emit('someone add you', { to, addMeData });
          }
        })
      }
    })

    socket.on('i accept your apply', async (msg) => {
      const { apply, accept } = msg;
      const r0 = await db2.find('chat', { userName: apply });
      const r1 = await db2.find('chat', { userName: accept });
      const applyUser = r1[0].friends.find(item => item.userName === apply);
      const acceptUser = r0[0].friends.find(item => item.userName === accept);

      const sockets = await io.fetchSockets();
      sockets.forEach((item) => {
        if (item.handshake.query.user === apply) {
          item.emit('update your friends list', acceptUser);
        } else if (item.handshake.query.user === accept) {
          item.emit('update your friends list', applyUser);
        }
      })
    })

    socket.on('send chat message', async (msg) => {
      // messageType 是消息类型
      // TEXT是普通文本或普通表情
      // IMAGE是图片资源
      // LINK是链接
      // BIGEMOJI是大表情
      // DATE是时间
      // COMPLEX是复杂类型，可能包含以上类型中的任意一种或多种。
      const { from, to } = msg;
      // 找到两人之间的最后一条消息
      const r0 = await db2.findCriteria('chatMessages', [{ $match: { $or: [{ 'from.userName': from, 'to.userName': to }, { 'from.userName': to, 'to.userName': from }] } }, { $sort: { date: -1 } }, { $limit: 1 }]);
      const r_from = await db2.find('users', { userName: from });
      const r_to = await db2.find('users', { userName: to });
      // 用于储存的消息
      const storeMessage = {
        messageId: from + '_' + to + '_' + Date.now(),
        from: {
          userName: r_from[0].userName,
          uid: r_from[0].uid,
          sex: r_from[0].sex,
          avatarUrl: r_from[0].avatarUrl
        },
        to: {
          userName: r_to[0].userName,
          uid: r_to[0].uid,
          sex: r_to[0].sex,
          avatarUrl: r_to[0].avatarUrl
        },
        content: msg.content,
        messageType: msg.messageType,
        date: Date.now(), // socket接收消息的时间
        isShowDate: (r0 && r0.length > 0) // 是否在前端显示该条消息的时间
          ? (Date.now() - r0[0].date) > 5 * 60 * 1000
            ? true
            : false
          : true,
        isRead: false, // 是否已读 默认false 未读
        isDeleted: false, // 是否被发送者删除（这里是删除是指发送者看不到这条消息，但是接收人还能看到）,
        isRecalled: false, // 是否被发送者撤回
      };
      await db2.addOne('chatMessages', storeMessage);

      // 更新firends里面的数据
      const lastChatMessage = {
        messageId: storeMessage.messageId,
        date: Date.now(),
        content: msg.content,
        messageType: msg.messageType
      };
      await db2.updateDeepKey('chat', { userName: from, 'friends.userName': to }, {
        'friends.$.lastMessage': lastChatMessage
      })
      await db2.updateDeepKey('chat', { userName: to, 'friends.userName': from }, {
        'friends.$.lastMessage': lastChatMessage
      })

      const sockets = await io.fetchSockets();
      let showTime = [];
      showTime = [
        {
          date: storeMessage.date,
          messageType: 'DATE'
        },
        storeMessage
      ];
      sockets.forEach(item => {
        if (item.handshake.query.user === to || item.handshake.query.user === from) {
          item.emit('i received your chat message', {
            messages: storeMessage.isShowDate
              ? showTime
              : [storeMessage]
          }, async (response) => {
            if (response.receiveUser === to && response.currentRoute === from) {
              await db2.updateManyKey('chatMessages', { 'from.userName': from, 'to.userName': to }, { isRead: true });
            }
          })
        }
        if (item.handshake.query.user === from) {
          item.emit('i should update our lastChatMessage', { chater: to, lastChatMessage });
        }
        if (item.handshake.query.user === to) {
          item.emit('i should update our lastChatMessage', { chater: from, lastChatMessage });
        }
      })
    })

    socket.on('i recalled a chat message', async (msg) => {
      const { from, to, messageId } = msg;
      await db2.updateKey('chatMessages', { 'from.userName': from.userName, 'to.userName': to.userName, messageId }, { isRecalled: true });

      const r0 = await db2.find('chat', { userName: from.userName });
      const isNeedUpdateLastMessage = r0[0].friends.find(item => item.lastMessage.messageId === messageId);

      const sockets = await io.fetchSockets();
      sockets.forEach(async (item) => {
        if (item.handshake.query.user === to.userName || item.handshake.query.user === from.userName) {

          if (isNeedUpdateLastMessage) {
            const lastChatMessage = {
              date: isNeedUpdateLastMessage.lastMessage.date,
              content: '',
              messageType: 'TEXT'
            };
            await db2.updateDeepKey('chat', { userName: from.userName, 'friends.userName': to.userName }, {
              'friends.$.lastMessage': {...lastChatMessage, content: '你撤回了一条消息'}
            })
            await db2.updateDeepKey('chat', { userName: to.userName, 'friends.userName': from.userName }, {
              'friends.$.lastMessage': {...lastChatMessage, content: '对方撤回了一条消息'}
            })

            if (item.handshake.query.user === from.userName) {
              item.emit('i should update our lastChatMessage', { chater: to.userName, lastChatMessage: { ...lastChatMessage, content: '你撤回了一条消息' } });
            }
            if (item.handshake.query.user === to.userName) {
              item.emit('i should update our lastChatMessage', { chater: from.userName, lastChatMessage: { ...lastChatMessage, content: '对方撤回了一条消息' } });
            }
          }

          if (item.handshake.query.user === from.userName) {
            item.emit('the chat message is recalled', to.userName);
          }
          if (item.handshake.query.user === to.userName) {
            item.emit('the chat message is recalled', from.userName);
          }
        }
      })
    })

    // ws断开连接时触发
    socket.on('disconnect', () => {
      console.log('后端：socket连接已断开...')
    })
    
  })
}